package org.apogee.mil.client.main.pages.admin.forms;

import java.util.ArrayList;
import org.apogee.mil.client.factories.ServerServiceFactory;
import org.apogee.mil.client.utils.CDCUtils;
import org.apogee.mil.client.utils.Session;
import org.apogee.mil.client.utils.Template;
import org.apogee.mil.shared.Constants.AccessLevelFields;
import org.apogee.mil.shared.Constants.DisplayFormat;
import org.apogee.mil.shared.User;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.form.FormButtonBinding;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.googlecode.gwt.crypto.client.TripleDesCipher;

public class AddUser extends LayoutContainer { 
	 private FormData formData;  
	 private VerticalPanel vp;
	 private TripleDesCipher cipher;
	 private int selectedAccess = -1;
	 private int sessionId = -1;
	 private User currentUser;
	 
	 public AddUser() {
		 this.currentUser = ServerServiceFactory.getUser(Session.getSessionId());;
		 this.sessionId = this.currentUser.getSessionId();
		 cipher = new TripleDesCipher();
		 cipher.setKey(CDCUtils.SECRET_KEY.getBytes());
	 }
	  
	  @Override  
	  protected void onRender(Element parent, int index) {  
	    super.onRender(parent, index);
	    formData = new FormData("-20");  
	    vp = new VerticalPanel();  
	    vp.setSpacing(10);  
	    createForm1();   
	    add(vp);    
	  }  
	  
	  private void createForm1() {  
	    FormPanel simple = new FormPanel();
	    simple.setHeading("Add User");
	    simple.setFrame(true);
	    simple.setWidth(500);
	    simple.setLabelWidth(100);
	    
	    final TextField<Integer> userId = new TextField<Integer>();  
	    userId.setFieldLabel("User ID"); 
	    userId.setAutoWidth(true);
	    userId.setAllowBlank(false);  
	    userId.getFocusSupport().setPreviousId(simple.getButtonBar().getId());
	    userId.focus();
	    simple.add(userId, formData); 
	    
	    final TextField<String> user = new TextField<String>();  
	    user.setFieldLabel("User Name"); 
	    user.setAutoWidth(true);
	    user.setAllowBlank(false);    
	    simple.add(user, formData);  
	  
	    final TextField<String> passwd = new TextField<String>();  
	    passwd.setFieldLabel("Password");  
	    passwd.setAllowBlank(false);  
	    passwd.setPassword(true);
	    passwd.setAutoWidth(true);
	    simple.add(passwd, formData); 
	    
	    final TextField<String> firstName = new TextField<String>();
	    firstName.setFieldLabel("First Name");
	    firstName.setAllowBlank(false);
	    firstName.setAutoWidth(true);
	    simple.add(firstName, formData);
	    
	    final TextField<String> lastName = new TextField<String>();
	    lastName.setFieldLabel("Last Name");
	    lastName.setAllowBlank(false);
	    lastName.setAutoWidth(true);
	    simple.add(lastName, formData);
	    
	    final ListStore<BaseModel> levels = new ListStore<BaseModel>();
	    
	    
	    ServerServiceFactory.getAdminService(sessionId).getAccessLevels(new AsyncCallback<ArrayList<BaseModel>>() {
			
			@Override
			public void onSuccess(ArrayList<BaseModel> result) {
				levels.add(result);
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				
			}
		});
	    
	    
	    final ComboBox<BaseModel> access = new ComboBox<BaseModel>();
	    access.setEmptyText("Access Level...");
	    access.setAllowBlank(false);
	    access.setFieldLabel("Access Level");
	    access.setStore(levels);
	    access.setDisplayField(DisplayFormat.DESCRIPTION_FMT);
	    access.setTemplate(Template.getAccessLevelTemplate());
	    access.setTriggerAction(TriggerAction.ALL);
	    access.addSelectionChangedListener(new SelectionChangedListener<BaseModel>() {
			
			@Override
			public void selectionChanged(SelectionChangedEvent<BaseModel> se) {
				access.select(se.getSelectedItem());
				try{
					String id = se.getSelectedItem().get(AccessLevelFields.ID);
					selectedAccess = Integer.parseInt(id);
				} catch (Exception ex) {
					selectedAccess = -1;
				} 
				
			}
		});
	    
	    simple.add(access);
	    
	    Button b = new Button("Add"); 
	    b.addSelectionListener(new SelectionListener<ButtonEvent>() {
			
			@Override
			public void componentSelected(ButtonEvent ce) {
				String idVal = String.valueOf(userId.getValue());
				int id = Integer.valueOf(idVal.trim());
				final String userName = user.getValue().trim();
				String pass = passwd.getValue().trim();
				
				String first = firstName.getValue().trim();
				String last = lastName.getValue().trim();
				
				try {
					pass =  cipher.encrypt(pass);
				} catch (Exception e) {
					MessageBox.info("Error", "Unable to add User", null);
					return;
				}
				
				if (selectedAccess < currentUser.getAccessLevel()) {
					MessageBox.info("Unable To Add User", "The access level given to the user is greater than your access level\n" +
							"Please choose a new access level", null);
				}

				ServerServiceFactory.getAdminService(sessionId).addUser(id, userName, pass, first, last, selectedAccess, "Y", new AsyncCallback<Boolean>() {
					
					@Override
					public void onSuccess(Boolean result) {
						if (result == true) {
							Info.display("Success", "User " + user + " Successfully Added");
							userId.clear();
							user.clear();
							passwd.clear();
							firstName.clear();
							lastName.clear();
							access.clear();
						}
						else {
							MessageBox.alert("Error", "Unable to Add User: " + user, null);
						}	
					}
					
					@Override
					public void onFailure(Throwable caught) {
						MessageBox.alert("Error", "Unable to Add User: " + user, null);
					}
				});				
			}
		});
	    simple.addButton(b);  
	    simple.setButtonAlign(HorizontalAlignment.CENTER);
	      
	    FormButtonBinding binding = new FormButtonBinding(simple);  
	    binding.addButton(b);
	 
	    add(simple);  
	  }
}
